package model

import (
	"errors"
	"gorm.io/gorm"
	"saleforce/sf-backend-user/constant"
	"strings"
	"time"
)

type MenuModel struct {
	Id         int64     `gorm:"primary_key;column:id;type:bigint" json:"id"`
	Name       string    `gorm:"column:name;type:varchar(255)" json:"name"`
	MenuType   int32     `gorm:"column:menu_type;type:tinyint" json:"menu_type"`
	IsShow     int32     `gorm:"column:is_show;type:tinyint" json:"is_show"`
	Created    time.Time `gorm:"column:created;type:datetime" json:"created"`
	Updated    time.Time `gorm:"column:updated;type:datetime" json:"updated"`
	Status     int32     `gorm:"column:status;type:tinyint" json:"status"`
	IsDel      int32     `gorm:"column:is_del;type:tinyint" json:"is_del"`
	ParentId   int64     `gorm:"column:parent_id;type:bigint" json:"parent_id"`
	ApiUrl     string    `gorm:"column:api_url;type:varchar(255)" json:"api_url"`
	ModuleLink string    `gorm:"column:module_link;type:varchar(255)" json:"module_link"`
	Icon       string    `gorm:"column:icon;type:varchar(255)" json:"icon"`
}

func (m MenuModel) GetMenuById(id int64) (*MenuModel, error) {
	tx := constant.Db.Model(&MenuModel{}).
		Omit("is_del").
		Where("id = ? and is_del = ?", id, 0).
		Find(&m)
	if tx.Error != nil {
		if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		return nil, errors.New("Database error")
	}
	return &m, nil
}

// ListByConditions 按条件分页查询
func (m MenuModel) ListByConditions(page int, size int, menuType *int32, status *int32, keyword *string) ([]MenuModel, error) {
	var lst []MenuModel
	if page < 1 {
		page = 1
	}
	if size < 1 {
		size = 10
	}
	var (
		conditions []string
		args       []interface{}
	)
	conditions = append(conditions, "is_del = ?")
	args = append(args, 0)
	if menuType != nil {
		conditions = append(conditions, " menu_type = ?")
		args = append(args, *menuType)
	}
	if status != nil && (*status == 0 || *status == 1) {
		conditions = append(conditions, " status = ?")
		args = append(args, *status)
	}
	if keyword != nil && *keyword != "" {
		kw := "%" + strings.TrimSpace(*keyword) + "%"
		conditions = append(conditions, " (name like ? or api_url like ? or module_link like ?)")
		args = append(args, kw, kw, kw)
	}
	query := strings.Join(conditions, " AND ")
	tx := constant.Db.Model(&MenuModel{}).
		Omit("is_del").
		Where(query, args...).
		Offset((page - 1) * size).
		Limit(size).
		Find(&lst)
	if tx.Error != nil {
		return []MenuModel{}, errors.New("Query error")
	}
	return lst, nil
}

// CountByConditions  按条件统计
func (m MenuModel) CountByConditions(menuType *int32, status *int32, keyword *string) int64 {
	var (
		conditions []string
		args       []interface{}
	)
	conditions = append(conditions, "is_del = ?")
	args = append(args, 0)
	if menuType != nil {
		conditions = append(conditions, " menu_type = ?")
		args = append(args, *menuType)
	}
	if status != nil && (*status == 0 || *status == 1) {
		conditions = append(conditions, " status = ?")
		args = append(args, *status)
	}
	if keyword != nil && *keyword != "" {
		kw := "%" + strings.TrimSpace(*keyword) + "%"
		conditions = append(conditions, " (name like ? or api_url like ? or module_link like ?)")
		args = append(args, kw, kw, kw)
	}
	query := strings.Join(conditions, " AND ")
	var count int64
	tx := constant.Db.Model(&MenuModel{}).
		Omit("is_del").
		Where(query, args...).
		Count(&count)
	if tx.Error != nil {
		return 0
	}
	return count
}

func (m MenuModel) ListByIds(ids []int64) ([]MenuModel, error) {
	if len(ids) == 0 {
		return []MenuModel{}, nil
	}
	var lst []MenuModel
	tx := constant.Db.Model(&MenuModel{}).
		Omit("is_del").
		Where("id in ? and is_del = ?", ids, 0).
		Find(&lst)
	if tx.Error != nil {
		return []MenuModel{}, errors.New("Database error")
	}
	return lst, nil
}

func (MenuModel) TableName() string {
	return "sf-menu"
}
